package com.peoit.honeycomb.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.MediaType;

import com.peoit.honeycomb.application.UserApplication;
import com.peoit.honeycomb.domain.User;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.google.common.net.HttpHeaders;
import com.peoit.honeycomb.domain.exception.FileUploadException;
import com.peoit.honeycomb.dto.Config;
import com.peoit.honeycomb.util.CommonUtil;

/**
 * Created by Bing.Zeng on 2015/9/22.
 */

public abstract class HoneycombBaseController {

	Logger logger = Logger.getLogger(HoneycombBaseController.class.getName());
	@Autowired
	UserApplication userApplication;

	/**
	 * 请求页面，封装返回view对象
	 *
	 * @param viewPath
	 * @param obj
	 * @return
	 */
	protected ModelAndView view(String viewPath, Object obj) {
		ModelAndView mav = new ModelAndView();
		mav.addObject("viewData", obj);
		mav.setViewName(viewPath);
		return mav;
	}

	protected ModelAndView view(String viewPath, Object obj, Object obj2) {
		ModelAndView mav = new ModelAndView();
		mav.addObject("viewData", obj);
		mav.addObject("queryData", obj2);
		mav.setViewName(viewPath);
		return mav;
	}

	protected ModelAndView viewWithName(String viewPath, String viewName, Object object) {
		ModelAndView mav = new ModelAndView();
		mav.addObject(viewName, object);
		mav.setViewName(viewPath);
		return mav;
	}

	/**
	 * 错误页面
	 * 
	 * @param viewPath
	 * @param viewData
	 * @param errorMsg
	 * @return
	 */
	protected ModelAndView error(String viewPath, Object viewData, String errorMsg) {
		ModelAndView mav = new ModelAndView();
		mav.addObject("viewData", viewData);
		mav.addObject("errorMsg", errorMsg);
		mav.setViewName(viewPath);
		return mav;
	}

	/**
	 * 请求页面，封装返回view对象
	 *
	 * @param viewPath
	 * @return
	 */
	protected ModelAndView view(String viewPath) {
		ModelAndView mav = new ModelAndView();
		mav.setViewName(viewPath);
		return mav;
	}

	//// http client 相关代码///////////////

	protected WebTarget restTarget(String uri) {
		String fullUri = Config.API_SERVER_URL;

		if (StringUtils.isBlank(uri)) {
			return ClientBuilder.newClient().register(MultiPartFeature.class).target(fullUri);
		}
		if (!uri.startsWith("/")) {
			fullUri += "/";
		}
		fullUri += uri;
		logger.info("Send rest request to : == " + fullUri);
		return ClientBuilder.newClient().register(MultiPartFeature.class).target(fullUri);
	}

	protected Invocation.Builder requestRest(String uri) {
		Invocation.Builder result = restTarget(uri).request();

		return result;
	}

	/**
	 * 传递多个parameters 给request
	 * 
	 * @param uri
	 * @param params
	 * @return
	 */
	protected Invocation.Builder requestRest(String uri, Map<String, Object> params) {
		Invocation.Builder result = null;
		WebTarget wt = restTarget(uri);
		if (params == null) {
			result = wt.request();
		}
		for (Map.Entry<String, Object> entry : params.entrySet()) {
			String key = entry.getKey();
			Object value = entry.getValue();
			wt = wt.queryParam(key, value);
			logger.info("key =====" + key);
			logger.info("value =====" + value);
		}
		result = wt.request();

		// TODO后期实现
		String accessToken = "";
		if (StringUtils.isNoneBlank(accessToken)) {
			result = result.header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken);
		}
		return result;
	}

	protected Entity jsonEntity(Object data) {
		return Entity.entity(data, MediaType.APPLICATION_JSON_TYPE);
	}

	protected Entity toUrlEntity(Object data) {
		return Entity.entity(data, MediaType.APPLICATION_FORM_URLENCODED);
	}

	protected Entity objectToEntity(Object data) {
		final Form form = new Form();

		try {

		} catch (Exception ex) {

		}

		logger.info("ObjectToEntity..............");
		return Entity.form(form);
	}

	/**
	 * 处理单个上传文件，存储到指定位置，返回文件路径
	 * 
	 * @param request
	 * @param file
	 * @return
	 */
	protected String storeUploadFile(HttpServletRequest request, MultipartFile file) {
		try {
			String newFileName = UUID.randomUUID().toString().replace("-", "");
			String folderPath = request.getRealPath("/upload");
			String extention = CommonUtil.getExtName(file.getOriginalFilename());
			String filePath = folderPath + File.separator + newFileName + extention;

			saveFile(file.getInputStream(), filePath);

			return "/upload/" + newFileName + "/" + extention;
		} catch (Exception ex) {
			ex.printStackTrace();
			throw new FileUploadException();
		}

	}

	/**
	 * 存储文件
	 * 
	 * @param stream
	 * @param fileFullPath
	 * @throws IOException
	 */
	private void saveFile(InputStream stream, String fileFullPath) throws IOException {
		FileOutputStream fs = null;
		try {
			fs = new FileOutputStream(fileFullPath);
			byte[] buffer = new byte[1024 * 1024];
			int bytesum = 0;
			int byteread = 0;
			while ((byteread = stream.read(buffer)) != -1) {
				bytesum += byteread;
				fs.write(buffer, 0, byteread);
				fs.flush();
			}
		} finally {
			fs.flush();
			fs.close();
			stream.close();
		}
	}

	public String getUserName() {
		return (String) SecurityUtils.getSubject().getSession().getAttribute("accessToken");
		// return this.getCurrentUser().getUserName();
	}

	public String getUserId() {
		return this.getCurrentUser().getId();
	}

	protected User getCurrentUser() {
		String id = (String) SecurityUtils.getSubject().getSession().getAttribute("accessTokenId");
		User userById = userApplication.getUserById(id);
		return userById;
	}

}
